package com.yixing.demo.component;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.yixing.demo.component.UserOnlineStatus;
import com.yixing.demo.constants.Constants;
import com.yixing.demo.mapper.MessageMapper;
import com.yixing.demo.mapper.MessageSessionMapper;
import com.yixing.demo.model.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.message.Message;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.Date;
import java.util.List;

@Slf4j
@Component
public class WebSocketClass extends TextWebSocketHandler {
    @Resource
    UserOnlineStatus userOnlineStatus;

    ObjectMapper objectMapper = new ObjectMapper();

    @Resource
    MessageSessionMapper messageSessionMapper;
    @Resource
    MessageMapper messageMapper;

    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        User user = (User) session.getAttributes().get(Constants.USER_SESSION);
        if(user == null) {
            log.info("当前用户未登录");
            return;
        }
        if(!userOnlineStatus.online(user.getUserId(), session)) {
            session.sendMessage(new TextMessage("{\"action\": \"redirect\"}"));
        }
    }


    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        Request request = objectMapper.readValue(message.getPayload(), Request.class);
        User user = (User) session.getAttributes().get(Constants.USER_SESSION);
        if(user == null) {
            log.info("当前用户未登录");
            return;
        }
        if(!request.getType().equals("message")) {
            log.info("request的type错误");
        }else {
            transmissionMessage(request, user);
        }

    }

    void transmissionMessage(Request request, User user) throws IOException {
        List<Friend> friends = messageSessionMapper.getFriendsBySessionId(request.getSessionId(), user.getUserId());
        Friend myself = new Friend();
        myself.setFriendId(user.getUserId());
        myself.setFriendName(user.getUsername());
        friends.add(myself);

        Response response = new Response();
        response.setFromId(user.getUserId());
        response.setFromName(user.getUsername());
        response.setSessionId(request.getSessionId());
        response.setContent(request.getContent());
        response.setPostTime(new Date());
        String respJson = objectMapper.writeValueAsString(response);

        for (Friend friend : friends) {
            WebSocketSession webSocketSession = userOnlineStatus.getWebSocketSessionByUserId(friend.getFriendId());
            if(webSocketSession == null) {
                continue;//说明当前用户不在线
            }
            webSocketSession.sendMessage(new TextMessage(respJson));
        }

        HistoryMessage historyMessage = new HistoryMessage();
        historyMessage.setFromId(user.getUserId());
        historyMessage.setSessionId(request.getSessionId());
        historyMessage.setContent(request.getContent());
        historyMessage.setPostTime(new Date());
        messageMapper.addMessage(historyMessage);
    }


    @Override
    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
        User user = (User) session.getAttributes().get(Constants.USER_SESSION);
        if(user == null) {
            return;
        }
        userOnlineStatus.offline(user.getUserId(), session);
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        User user = (User) session.getAttributes().get(Constants.USER_SESSION);
        if(user == null) {
            return;
        }
        userOnlineStatus.offline(user.getUserId(), session);
    }
}
